package com.gasstation

import java.text.DateFormat
import java.text.SimpleDateFormat

import com.gasstation.domain.GasUtil
import com.gasstation.domain.ShowOpenActualInvCostField

class GasSalesController {

	static allowedMethods = [save: "POST", update: "POST"]

	def index = {
		redirect(action: "create", params: params)
	}

	def list = {
		params.max = Math.min(params.max ? params.int('max') : 10, 100)
		[gasSalesInstanceList: GasSales.list(params), gasSalesInstanceTotal: GasSales.count(), monthYear:new Date()]
	}
	def listAsPerMonth = {
		params.max = Math.min(params.max ? params.int('max') : 10, 100)
		def c = GasSales.createCriteria()
		Date month = params.monthYear
		if(month == null){
			month = new Date()
		}
		def gasList = c.list{between("transactionOn", GasUtil.getFirstDayOfMonth(month), GasUtil.getLastDayOfMonth(month))}
		render(view: "list", model: [gasSalesInstanceList:gasList, monthYear:month, gasSalesInstanceTotal: GasSales.count()])
	}

	def create = {
		Date transactionOn = null
		Object date = params.transactionOnStr
		DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy")
		if(date instanceof String){
			transactionOn = formatter.parse(date)
		}
		if(transactionOn == null){
			transactionOn = new Date()
		}
		transactionOn = GasUtil.getStartDate(transactionOn)

		def gasSalesInstance = GasSales.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
		if(gasSalesInstance == null){
			gasSalesInstance = new GasSales()
		}

		gasSalesInstance.properties = params
		def showOpenActualInvCostField = new ShowOpenActualInvCostField()
		showRegularOpenActualFields(gasSalesInstance, showOpenActualInvCostField, transactionOn)
		showMidGradeOpenActualFields(gasSalesInstance, showOpenActualInvCostField, transactionOn)
		showPremiumOpenActualFields(gasSalesInstance, showOpenActualInvCostField, transactionOn)
		def inventoryRegularInstance = InventoryRegular.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
		def inventoryMidGradeInstance = InventoryMidGrade.findByTransactionOnBetween(GasUtil.getPreviousDate(-1,transactionOn), GasUtil.getPreviousDate(0, transactionOn))
		def inventoryPremiumInstance = InventoryPremium.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))

		def regularActualGallons = 0
		if(inventoryRegularInstance!=null){
			regularActualGallons=inventoryRegularInstance.regularActualGallons
		}
		def midGradeActualGallons = 0
		if(inventoryMidGradeInstance!=null){
			midGradeActualGallons=inventoryMidGradeInstance.midGradeActualGallons
		}
		def premiumActualGallons = 0
		if(inventoryPremiumInstance!=null){
			premiumActualGallons=inventoryPremiumInstance.premiumActualGallons
		}
		return [gasSalesInstance: gasSalesInstance, showOpenActualInvCostField:showOpenActualInvCostField,
			transactionOnStr:formatter.format(transactionOn), transactionOn:transactionOn,
			regularActualGallons:regularActualGallons,
			midGradeActualGallons:midGradeActualGallons,
			premiumActualGallons:premiumActualGallons
		]
	}

	def save = {
		Date transactionOn = null
		Object date = params.transactionOnStr
		DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy")
		if(date instanceof String){
			transactionOn = formatter.parse(date)
		}
		if(transactionOn == null){
			transactionOn = new Date()
		}
		transactionOn = GasUtil.getStartDate(transactionOn)

		params.transactionOn= transactionOn
		def gasSalesInstance = GasSales.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
		if(gasSalesInstance == null){
			gasSalesInstance = new GasSales(params)
		}
		GasSales.withTransaction{ status ->
			try{
				if (gasSalesInstance.save(flush: true, failOnError:true)) {
					flash.message = "${message(code: 'default.created.message', args: [message(code: 'gasSales.label', default: 'GasSales'), gasSalesInstance.id])}"
					session.regSalesPricePerGallon = gasSalesInstance.regularPricePerGallon
					session.midSalesPricePerGallon = gasSalesInstance.midGradePricePerGallon
					session.premiumSalesPricePerGallon = gasSalesInstance.premiumPricePerGallon

					def inventoryRegularInstance = InventoryRegular.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
					if(inventoryRegularInstance == null){
						inventoryRegularInstance = new InventoryRegular(params)
						String regNetGallons = params.regularNetGallons
						if(regNetGallons !=null && !"".equals(regNetGallons) && Double.parseDouble(regNetGallons) > 0){
							inventoryRegularInstance.regularSaleGallons = Double.parseDouble(regNetGallons)
						}
					}else{
						String regOpenGallons = params.regularOpenGallons
						String regOpenInvCost = params.regularOpenInvCost
						String regActualGallons = params.regularActualGallons
						String regNetGallons = params.regularNetGallons

						if(regOpenGallons !=null && !"".equals(regOpenGallons) && Double.parseDouble(regOpenGallons) > 0){
							inventoryRegularInstance.regularOpenGallons = Double.parseDouble(regOpenGallons)
						}
						if(regOpenInvCost !=null && !"".equals(regOpenInvCost) && Double.parseDouble(regOpenInvCost) > 0){
							inventoryRegularInstance.regularOpenInvCost = Double.parseDouble(regOpenInvCost)
						}
						if(regActualGallons !=null && !"".equals(regActualGallons) && Double.parseDouble(regActualGallons) > 0){
							inventoryRegularInstance.regularActualGallons = Double.parseDouble(regActualGallons)
						}
						if(regNetGallons !=null && !"".equals(regNetGallons) && Double.parseDouble(regNetGallons) > 0){
							inventoryRegularInstance.regularSaleGallons = Double.parseDouble(regNetGallons)
						}
					}
					def inventoryPreviousRegularInstance = InventoryRegular.findByTransactionOnBetween(GasUtil.getPreviousDate(-2, transactionOn), GasUtil.getPreviousDate(-1, transactionOn))
					if(inventoryPreviousRegularInstance!=null){
						inventoryRegularInstance.regularOpenGallons = inventoryPreviousRegularInstance.regularCloseGallons
						inventoryRegularInstance.regularOpenInvCost = inventoryPreviousRegularInstance.regularOpenInvCost + inventoryPreviousRegularInstance.regularPurchasedCost - inventoryPreviousRegularInstance.regularCost
					}
					GasUtil.saveInventoryRegular(inventoryRegularInstance)
					GasUtil.updateSubsequentInventoryRegular(inventoryRegularInstance, transactionOn)

					def inventoryMidGradeInstance = InventoryMidGrade.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
					if(inventoryMidGradeInstance == null){
						inventoryMidGradeInstance = new InventoryMidGrade(params)
						String midNetGallons = params.midGradeNetGallons
						if(midNetGallons !=null && !"".equals(midNetGallons) && Double.parseDouble(midNetGallons) > 0){
							inventoryMidGradeInstance.midGradeSaleGallons = Double.parseDouble(midNetGallons)
						}
					}else{
						String midOpenGallons = params.midGradeOpenGallons
						String midOpenInvCost = params.midGradeOpenInvCost
						String midActualGallons = params.midGradeActualGallons
						String midNetGallons = params.midGradeNetGallons

						if(midOpenGallons !=null && !"".equals(midOpenGallons) && Double.parseDouble(midOpenGallons) > 0){
							inventoryMidGradeInstance.midGradeOpenGallons = Double.parseDouble(midOpenGallons)
						}
						if(midOpenInvCost !=null && !"".equals(midOpenInvCost) && Double.parseDouble(midOpenInvCost) > 0){
							inventoryMidGradeInstance.midGradeOpenInvCost = Double.parseDouble(midOpenInvCost)
						}
						if(midActualGallons !=null && !"".equals(midActualGallons) && Double.parseDouble(midActualGallons) > 0){
							inventoryMidGradeInstance.midGradeActualGallons = Double.parseDouble(midActualGallons)
						}
						if(midNetGallons !=null && !"".equals(midNetGallons) && Double.parseDouble(midNetGallons) > 0){
							inventoryMidGradeInstance.midGradeSaleGallons = Double.parseDouble(midNetGallons)
						}
					}
					def inventoryPreviousMidGradeInstance = InventoryMidGrade.findByTransactionOnBetween(GasUtil.getPreviousDate(-2, transactionOn), GasUtil.getPreviousDate(-1, transactionOn))
					if(inventoryPreviousMidGradeInstance!=null){
						inventoryMidGradeInstance.midGradeOpenGallons = inventoryPreviousMidGradeInstance.midGradeCloseGallons
						inventoryMidGradeInstance.midGradeOpenInvCost = inventoryPreviousMidGradeInstance.midGradeOpenInvCost + inventoryPreviousMidGradeInstance.midGradePurchasedCost - inventoryPreviousMidGradeInstance.midGradeCost
					}
					GasUtil.saveInventoryMidGrade(inventoryMidGradeInstance)
					GasUtil.updateSubsequentInventoryMidGrade(inventoryMidGradeInstance, transactionOn)

					def inventoryPremiumInstance = InventoryPremium.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
					if(inventoryPremiumInstance == null){
						inventoryPremiumInstance = new InventoryPremium(params)
						String preNetGallons = params.premiumNetGallons
						if(preNetGallons !=null && !"".equals(preNetGallons) && Double.parseDouble(preNetGallons) > 0){
							inventoryPremiumInstance.premiumSaleGallons = Double.parseDouble(preNetGallons)
						}
					}else{
						String preOpenGallons = params.premiumOpenGallons
						String preOpenInvCost = params.premiumOpenInvCost
						String preActualGallons = params.premiumActualGallons
						String preNetGallons = params.premiumNetGallons

						if(preOpenGallons !=null && !"".equals(preOpenGallons) && Double.parseDouble(preOpenGallons) > 0){
							inventoryPremiumInstance.premiumOpenGallons = Double.parseDouble(preOpenGallons)
						}
						if(preOpenInvCost !=null && !"".equals(preOpenInvCost) && Double.parseDouble(preOpenInvCost) > 0){
							inventoryPremiumInstance.premiumOpenInvCost = Double.parseDouble(preOpenInvCost)
						}
						if(preActualGallons !=null && !"".equals(preActualGallons) && Double.parseDouble(preActualGallons) > 0){
							inventoryPremiumInstance.premiumActualGallons = Double.parseDouble(preActualGallons)
						}
						if(preNetGallons !=null && !"".equals(preNetGallons) && Double.parseDouble(preNetGallons) > 0){
							inventoryPremiumInstance.premiumSaleGallons = Double.parseDouble(preNetGallons)
						}
					}
					def inventoryPreviousPremiumInstance = InventoryPremium.findByTransactionOnBetween(GasUtil.getPreviousDate(-2, transactionOn), GasUtil.getPreviousDate(-1, transactionOn))
					if(inventoryPreviousPremiumInstance!=null){
						inventoryPremiumInstance.premiumOpenGallons = inventoryPreviousPremiumInstance.premiumCloseGallons
						inventoryPremiumInstance.premiumOpenInvCost = inventoryPreviousPremiumInstance.premiumOpenInvCost + inventoryPreviousPremiumInstance.premiumPurchasedCost - inventoryPreviousPremiumInstance.premiumCost
					}
					GasUtil.saveInventoryPremium(inventoryPremiumInstance)
					GasUtil.updateSubsequentInventoryPremium(inventoryPremiumInstance, transactionOn)

					redirect(action: "listAsPerMonth")
				}
				else {
					render(view: "create", model: [gasSalesInstance: gasSalesInstance])
				}
			}catch(Exception e){
				e.printStackTrace()
				gasSalesInstance.errors.reject(e.getMessage())
				status.setRollbackOnly()
			}
		}
	}

	def show = {
		def gasSalesInstance = GasSales.get(params.id)
		if (!gasSalesInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'gasSales.label', default: 'GasSales'), params.id])}"
			redirect(action: "list")
		}
		else {
			[gasSalesInstance: gasSalesInstance]
		}
	}

	def edit = {
		def gasSalesInstance = GasSales.get(Long.valueOf(params.id))
		if (!gasSalesInstance) {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'gasSales.label', default: 'GasSales'), params.id])}"
			redirect(action: "listAsPerMonth")
		}
		else {
			return [gasSalesInstance: gasSalesInstance]
		}
	}

	def update = {
		def gasSalesInstance = GasSales.get(Long.valueOf(params.id))
		if (gasSalesInstance) {
			if (params.version) {
				def version = params.version.toLong()
				if (gasSalesInstance.version > version) {

					gasSalesInstance.errors.rejectValue("version", "default.optimistic.locking.failure", [
						message(code: 'gasSales.label', default: 'GasSales')]
					as Object[], "Another user has updated this GasSales while you were editing")
					render(view: "edit", model: [gasSalesInstance: gasSalesInstance])
					return
				}
			}
			gasSalesInstance.properties = params
			if (!gasSalesInstance.hasErrors() && gasSalesInstance.save(flush: true)) {
				flash.message = "${message(code: 'default.updated.message', args: [message(code: 'gasSales.label', default: 'GasSales'), gasSalesInstance.id])}"
				redirect(action: "listAsPerMonth")
			}
			else {
				render(view: "edit", model: [gasSalesInstance: gasSalesInstance])
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'gasSales.label', default: 'GasSales'), params.id])}"
			redirect(action: "listAsPerMonth")
		}
	}

	def delete = {
		def gasSalesInstance = GasSales.get(Long.valueOf(params.id))
		if (gasSalesInstance) {
			try {
				gasSalesInstance.delete(flush: true)
				flash.message = "${message(code: 'default.deleted.message', args: [message(code: 'gasSales.label', default: 'GasSales'), params.id])}"
				redirect(action: "listAsPerMonth")
			}
			catch (org.springframework.dao.DataIntegrityViolationException e) {
				flash.message = "${message(code: 'default.not.deleted.message', args: [message(code: 'gasSales.label', default: 'GasSales'), params.id])}"
				redirect(action: "listAsPerMonth", id: params.id)
			}
		}
		else {
			flash.message = "${message(code: 'default.not.found.message', args: [message(code: 'gasSales.label', default: 'GasSales'), params.id])}"
			redirect(action: "listAsPerMonth")
		}
	}

	private showRegularOpenActualFields(GasSales gasSalesInstance, ShowOpenActualInvCostField showOpenActualInvCostField, Date transactionOn) {
		def inventoryRegularInstance = InventoryRegular.findByTransactionOnBetween(GasUtil.getPreviousDate(-2, transactionOn), GasUtil.getPreviousDate(-1, transactionOn))
		if(inventoryRegularInstance == null){
			inventoryRegularInstance = InventoryRegular.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
		}
		if(inventoryRegularInstance!=null){
			if(inventoryRegularInstance.regularOpenGallons ==null ||inventoryRegularInstance.regularOpenGallons==0){
				showOpenActualInvCostField.showRegularOpenGallonsField = true
			}
			//			if(inventoryRegularInstance.regularActualGallons ==null ||inventoryRegularInstance.regularActualGallons==0){
			//				showOpenActualInvCostField.showRegularActualGallonsField = true
			//			}
			if(inventoryRegularInstance.regularOpenInvCost ==null ||inventoryRegularInstance.regularOpenInvCost==0){
				showOpenActualInvCostField.showRegularOpenInvCostField = true
			}
		}else{
			showOpenActualInvCostField.showRegularOpenGallonsField = true
			//			showOpenActualInvCostField.showRegularActualGallonsField = true
			showOpenActualInvCostField.showRegularOpenInvCostField = true
		}
	}
	private showMidGradeOpenActualFields(GasSales gasSalesInstance, ShowOpenActualInvCostField showOpenActualInvCostField, Date transactionOn) {
		def inventoryMidGradeInstance = InventoryMidGrade.findByTransactionOnBetween(GasUtil.getPreviousDate(-2, transactionOn), GasUtil.getPreviousDate(-1, transactionOn))
		if(inventoryMidGradeInstance == null){
			inventoryMidGradeInstance = InventoryMidGrade.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
		}
		if(inventoryMidGradeInstance!=null){
			if(inventoryMidGradeInstance.midGradeOpenGallons ==null ||inventoryMidGradeInstance.midGradeOpenGallons==0){
				showOpenActualInvCostField.showMidGradeOpenGallonsField = true
			}
			//			if(inventoryMidGradeInstance.midGradeActualGallons ==null ||inventoryMidGradeInstance.midGradeActualGallons==0){
			//				showOpenActualInvCostField.showMidGradeActualGallonsField = true
			//			}
			if(inventoryMidGradeInstance.midGradeOpenInvCost ==null ||inventoryMidGradeInstance.midGradeOpenInvCost==0){
				showOpenActualInvCostField.showMidGradeOpenInvCostField = true
			}
		}else{
			showOpenActualInvCostField.showMidGradeOpenGallonsField = true
			//			showOpenActualInvCostField.showMidGradeActualGallonsField = true
			showOpenActualInvCostField.showMidGradeOpenInvCostField = true
		}
	}
	private showPremiumOpenActualFields(GasSales gasSalesInstance, ShowOpenActualInvCostField showOpenActualInvCostField, Date transactionOn) {
		def inventoryPremiumInstance = InventoryPremium.findByTransactionOnBetween(GasUtil.getPreviousDate(-2, transactionOn), GasUtil.getPreviousDate(-1, transactionOn))
		if(inventoryPremiumInstance == null){
			inventoryPremiumInstance = InventoryPremium.findByTransactionOnBetween(GasUtil.getPreviousDate(-1, transactionOn), GasUtil.getPreviousDate(0, transactionOn))
		}
		if(inventoryPremiumInstance!=null){
			if(inventoryPremiumInstance.premiumOpenGallons ==null ||inventoryPremiumInstance.premiumOpenGallons==0){
				showOpenActualInvCostField.showPremiumOpenGallonsField = true
			}
			//			if(inventoryPremiumInstance.premiumActualGallons ==null ||inventoryPremiumInstance.premiumActualGallons==0){
			//				showOpenActualInvCostField.showPremiumActualGallonsField = true
			//			}
			if(inventoryPremiumInstance.premiumOpenInvCost ==null ||inventoryPremiumInstance.premiumOpenInvCost==0){
				showOpenActualInvCostField.showPremiumOpenInvCostField = true
			}
		}else{
			showOpenActualInvCostField.showPremiumOpenGallonsField = true
			//			showOpenActualInvCostField.showPremiumActualGallonsField = true
			showOpenActualInvCostField.showPremiumOpenInvCostField = true
		}
	}
}
